﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;


//using System.Windows.Forms.DataVisualization;
using System.Windows.Forms.DataVisualization.Charting;

using SpectationClient.SpectralTools;
using SpectationClient.Stuff;
using SpectationClient.DGVExtensions;
using SpectationClient;
using SpectationClient.GUI.UC;
using SpectationClient.DataBaseDescription;
using Npgsql;

namespace SpectralViewer {
    public partial class SpectralViewer : Form {
        //private DataTable spectra = new DataTable();
        private Random random = new Random(42);
        private BindingSource bindingSource = new BindingSource();
        private UC_SpectralViewer UCSPEC;
        public SpectralViewer() {
            InitializeComponent();

            this.listViewSpectralFile.Columns.Add("Name", -2, HorizontalAlignment.Left);
            this.listViewSpectralFile.Columns.Add("Type", -2, HorizontalAlignment.Left);
            this.listViewSpectralFile.Columns.Add("Spectra", -2, HorizontalAlignment.Left);
            this.listViewSpectralFile.Columns.Add("Path", -2, HorizontalAlignment.Left);
            /*
            this.spectra.Columns.Add("CSPECTRA", typeof(SPECTATION_Client.SpectralTools.Spectrum));
            this.spectra.Columns.Add("CCOLORS", typeof(Color));
            this.spectra.Columns.Add("CSOURCE", typeof(ListViewItem));
            */

            //DataGridView
            this.DGVSpectra.DataError +=new DataGridViewDataErrorEventHandler(DGVSpectra_DataError);

            this.UCSPEC = new UC_SpectralViewer();
            this.UCSPEC.linkToSpectrumColumn(CSPECTRA, CCOLORS);
            this.UCSPEC.LegendTitle = "Spectra";
            this.UCSPEC.Dock = DockStyle.Fill;
            splitContainer1.Panel1.Controls.Add(UCSPEC);
            UCSPEC.Show();
           

#if DEBUG
            testInit();
#endif
        }

        void DGVSpectra_DataError(object sender, DataGridViewDataErrorEventArgs e) {
            
            SpectationClient.Stuff.FormHelper.ShowErrorBox(e.Exception);
        }

        private void testInit() {
            String[] spectra = new String[]{
                   // @"Z:\BeispielPotsdam\reflectance\reflectance\doeb_1_010900000.asd.ref",
                    @"Z:\BeispielPotsdam\reflectance\reflectance\doeb_1_010900001.asd.ref",
                    @"Z:\BeispielPotsdam\reflectance\reflectance\doeb_1_010900002.asd.ref",
                    @"Z:\BeispielPotsdam\esl\doe090901_jump_resamp.esl"
            };
            addSpectra(spectra);
        
        }


        private bool t(int i, int j=5) {
            return j == 5;
        }

        private enum spectype : byte { 
            asd = 0,
            esl = 1
        }
        

        /// <summary>
        /// Reads spectra from spectral files and adds them to the data grid and the list of spectral files
        /// </summary>
        /// <param name="fileNames"></param>
        public void addSpectra(IEnumerable<String> fileNames) {
            ListViewGroup groupESL = this.listViewSpectralFile.Groups["groupESL"];
            ListViewGroup groupASD = this.listViewSpectralFile.Groups["groupASD"];
            var spectralFiles = (from path in fileNames
                                 let isASD = ASD_Reader.isValidASDSpectrum(path)
                                 let isESL = ESL_Reader.isValidFile(path)
                                 where File.Exists(path) && (isASD || isESL)
                                 select new {
                                     fileInfo = new FileInfo(path),
                                     fileType = isASD ? Spectrum.SpectrumFileType.ASD :
                                                        Spectrum.SpectrumFileType.ESL
                                 }
                                );



            //List<Spectrum> newSpectra = new List<Spectrum>();
            foreach(var info in spectralFiles) {
                if(listViewSpectralFile.Items.ContainsKey(info.fileInfo.FullName)) continue;

               
                ListViewItem item = new ListViewItem();
                item.Name = info.fileInfo.FullName;
                item.Text = info.fileInfo.Name;
                item.Checked = true;
                item.SubItems.Add(info.fileType.ToString()); //file type
                
                
                
                switch(info.fileType) {
                    case Spectrum.SpectrumFileType.ESL:
                        FileInfo headerFile;
                        FileInfo binaryFile;
                        bool b = ENVI_FileReader.findFileInfos(info.fileInfo, out binaryFile, out headerFile);
                        if(ESL_Reader.isValidFile(binaryFile)) {
                            ESL_Reader eslReader2 = new ESL_Reader(binaryFile, headerFile);
                            List<Spectrum> eslSpectra = eslReader2.readSpectra();
                            item.Tag = eslSpectra;
                            //newSpectra.AddRange(eslSpectra);
                            item.SubItems.Add(eslSpectra.Count.ToString());
                            item.Group = groupESL;
                        }

                        break;
                    case Spectrum.SpectrumFileType.ASD:
                        List<Spectrum> spectrum = new List<Spectrum>(){ASD_Reader.readSpectrum(info.fileInfo)};
                        item.Tag = spectrum;
                        item.SubItems.Add("1");
                        item.Group = groupASD;
                        break;
                }
                item.SubItems.Add(info.fileInfo.FullName); //full path
                
                listViewSpectralFile.Items.Add(item);

            }

            //return this.addSpectra(newSpectra);
        }

      


        public List<Spectrum> getSelectedSpectra() {
            List<Spectrum> spectra = new List<Spectrum>();
            int iSpec = this.CSPECTRA.Index;

            foreach(DataGridViewRow row in DGVSpectra.Rows) {
                if(row.Selected) {
                    DataGridViewSpectrumCell cell = row.Cells[iSpec] as DataGridViewSpectrumCell;
                    if(cell != null && cell.Value != null) spectra.Add(cell.getSpectrum());
                }
            }
            return spectra;
        }
       

        private Color getColor() {
            Color x = Color.ForestGreen;
            return Color.FromArgb(255,
                this.random.Next(0, 255),
                this.random.Next(0, 255),
                this.random.Next(0, 255)
                );

        }


        private void listViewSpectralFile_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) {
            
            this.btRemove.Enabled = listViewSpectralFile.SelectedItems.Count > 0;

            
            if(e.IsSelected) {
                //add 
                foreach(Spectrum spec in e.Item.Tag as List<Spectrum>) {
                    DGVSpectra.Rows.Add(new Object[] { spec, getColor(), spec.FileName, e.Item });
                }

            } else {
              
                for(int i = DGVSpectra.Rows.Count - 1; i >= 0; i--) {
                    if(DGVSpectra["ItemLink", i].Value == e.Item) {
                        DGVSpectra.Rows.RemoveAt(i);
                    
                    }
                
                }
            
            }
            /*
            //selected
            List<ListViewItem> selectedItems = new List<ListViewItem>();
            foreach(ListViewItem item in listViewSpectralFile.SelectedItems) {
                selectedItems.Add(item);
            }

            //to remove 
            var toRemove = from DataGridViewRow r in DGVSpectra.Rows
                           let item = r.Cells["ItemLink"].Value as ListViewItem
                           where 


            String s = "";
            foreach(DataGridViewRow row in DGVSpectra.Rows) {
                ListViewItem item = row.Cells["ItemLink"].Value as ListViewItem;
                if(selectedItems.Contains(item)) {
                    selectedItems.Remove(item);//item already added
                    if(selectedItems.Count == 0) break;
                }
            }
            //add 
            foreach(ListViewItem item in selectedItems) {
                foreach(Spectrum spec in item.Tag as List<Spectrum>) {
                    DGVSpectra.Rows.Add(new Object[] { spec, getColor(), spec.FileName, item });
                }
            }

            // to remove
            for(int i = DGVSpectra.Rows.Count - 1; i >= 0; i--) {
                ListViewItem item = DGVSpectra["ItemLink", i].Value as ListViewItem;
                if(!selectedItems.Contains(item)){
                    DGVSpectra.Rows.RemoveAt(i);
                }
            }
            /*
            var xToRemove = from DataGridViewRow row in DGVSpectra.Rows
                            let item = row.Cells["ItemLink"].Value as ListViewItem
                            where !selectedItems.Contains(item)
                            select row ;
            foreach(DataGridViewRow row in xToRemove) {
                DGVSpectra.Rows.RemoveAt(row.Index);
            }*/
            
            
        }

        private void btAdd_Click(object sender, EventArgs e) {
            OpenFileDialog OFD = new OpenFileDialog();
            OFD.Multiselect = true;
            if(OFD.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
                this.addSpectra(OFD.FileNames);

            }
        }

        private void btRemove_Click(object sender, EventArgs e) {
            foreach(ListViewItem item in listViewSpectralFile.SelectedItems) {
                listViewSpectralFile.Items.Remove(item);
            }
        }

    }
}
